var express = require('express');
var router = express.Router();
var jwt = require('jsonwebtoken');
var path = require('path');
const multer = require('multer');
const upload = multer({ dest: 'uploads/' });
const fs = require('fs');
// 短信
const tencentcloud = require("tencentcloud-sdk-nodejs")
const { UserInfoModel, MenuModel } = require('../mongoose/models.js');
/* GET home page. */

// 文件上传
// 处理文件上传的路由
// 存储文件哈希值的对象
const fileHashes = {};

router.post("/upload", upload.single('file'), (req, res) => {
  // 获取上传的文件对象
  const file = req.file;

  // 获取文件名
  const filename = req.body.filename;

  // 获取总块数和当前块数
  const totalChunks = parseInt(req.body.totalChunks);
  const currentChunk = parseInt(req.body.currentChunk);

  // 生成当前块的存储路径
  const chunkPath = path.join(__dirname, '../upload', `${filename}-chunk-${currentChunk}`);

  // 创建读取文件块的可读流和写入当前块的可写流
  const chunkStream = fs.createReadStream(file.path);
  const writeStream = fs.createWriteStream(chunkPath);

  // 将读取的文件块内容通过管道写入当前块的文件
  chunkStream.pipe(writeStream);

  // 监听读取文件块流结束事件
  chunkStream.on('end', () => {
    fs.unlinkSync(file.path); // 读取文件块的流结束后，删除临时文件
    const progress = ((currentChunk + 1) / totalChunks) * 100;  //计算上传进度
    res.json({ progress }); // 响应上传成功的状态码
  });
});

// 处理文件合并的路由
router.post('/merge', (req, res) => {
  // 获取文件名和总块数
  const filename = req.body.filename;
  const totalChunks = parseInt(req.body.totalChunks);
  const fileHash = req.body.fileHash;

  // 生成合并后文件的存储路径
  const mergedPath = path.join(__dirname, '../upload', filename);

  // 创建写入合并后文件的可写流
  const writeStream = fs.createWriteStream(mergedPath);

  // 递归合并文件块的函数
  const mergeChunks = (index) => {
    if (index === totalChunks) {
      writeStream.end(); // 所有块都合并完成后，关闭写入流
      res.sendStatus(200); // 响应合并成功的状态
      return;
    }

    // 获取当前块的存储路径
    const chunkPath = path.join(__dirname, '../upload', `${filename}-chunk-${index}`);

    // 同步读取当前块的内容
    const chunk = fs.readFileSync(chunkPath);

    // 删除已合并的块
    fs.unlinkSync(chunkPath);

    // 存储文件哈希值
    fileHashes[fileHash] = true;

    // 将块的内容写入合并后文件，并在写入完成后递归合并下一块
    writeStream.write(chunk, () => {
      mergeChunks(index + 1);
    });
  };

  // 开始递归合并文件块
  mergeChunks(0);
});

router.head('/check-file', (req, res) => {
  const fileHash = req.query.filehash;
  console.log(fileHash, fileHashes);
  if (fileHashes[fileHash]) {
    res.sendStatus(200); //文件已存在
  } else {
    res.sendStatus(404); //文件不存在
  }
})



// 注册
router.post('/register', async (req, res) => {
  try {
    const { email, password, phone } = req.body;

    const register = {
      username: '新生用户',
      email,
      password,
      avatar: 'https://qn.wanghq.pro/ImageFiles/cz.jpg',
      phone,
    };

    const data = await UserInfoModel.create(register);

    const token = generateToken(username);

    res.status(200).json({
      code: 200,
      msg: '注册成功',
      data,
      token,
    });
  } catch (error) {
    console.error(error);
    res.status(500).json({
      code: 500,
      msg: '服务器错误',
    });
  }
});

// 登录
router.post("/login", async (req, res) => {
  try {
    const userEmail = await UserInfoModel.findOne({ email: req.body.email });
    if (!userEmail) {
      return res.send({
        code: 204,
        msg: 'USER_NOT_FOUND',
      });
    }
    const userInfo = await UserInfoModel.findOne(req.body).exec();
    if (!userInfo) {
      return res.send({
        code: 201,
        msg: 'USER_NOT_LOGIN',
      });
    }
    const token = generateToken(userInfo.email);

    res.send({
      code: 200,
      msg: '登录成功',
      userInfo,
      token,
    });
  } catch (error) {
    res.send({
      code: 500,
      msg: '服务器错误',
    });
  }
});

function generateToken(nickName) {
  const token = jwt.sign({ name: nickName }, 'flag', { expiresIn: '1h' });
  return `Bearer ${token}`;
}

// 列表
router.get('/Menu', async (req, res) => {
  let menu = await MenuModel.find()
  res.send({ code: 200, msg: 'GET_MENU', menu })
})

// 微信登录
router.post("/loginother", async (req, res) => {
  let body = req.body
  let prodata = {
    name: body.nickName,
    password: '',
    base: '',
    avatar: body.avatar,
    fullname: body.nickName,
    state: '',
    captcha: '',
    phone: '',
    email: '',
    position: '',
    qrcode: '',
    provider: body.provider,
    openid: body.openId,
    friends: [],
  }
  let data = await UserModel.findOne({ openid: body.openId }).exec();
  console.log('----------', data, '----------');
  if (data === null) {
    let data = await UserModel.create(prodata)
    let token = "Bearer" + " " + jwt.sign({ name: body.nickName }, 'flag', { expiresIn: 10000 })
    console.log("程序一 :未登录过");
    res.send({
      code: 200,
      msg: '登录成功',
      data,
      token
    })
  } else if (data) {
    let token = "Bearer" + " " + jwt.sign({ name: body.nickName }, 'flag', { expiresIn: 10000 })
    console.log("程序二 :登录过");
    res.send({
      code: 200,
      msg: '登录成功',
      data,
      token
    })
  } else {
    res.send({
      code: 201,
      msg: '登录失败',
    })
  }
})

// 腾讯云短信接口
router.post('/phonecode', async (req, res) => {
  let { phone } = req.body
  // 导入对应产品模块的client models。
  const smsClient = tencentcloud.sms.v20210111.Client
  /* 实例化要请求产品(以sms为例)的client对象 */
  const client = new smsClient({
    credential: {
      /* 必填：腾讯云账户密钥对secretId，secretKey。
       * 这里采用的是从环境变量读取的方式，需要在环境变量中先设置这两个值。
       * 你也可以直接在代码中写死密钥对，但是小心不要将代码复制、上传或者分享给他人，
       * 以免泄露密钥对危及你的财产安全。
       * SecretId、SecretKey 查询: https://console.cloud.tencent.com/cam/capi */
      secretId: 'AKIDEMHgNp20jDSSDm8F9A1d1B7rOgjX7Smx',
      secretKey: 'FNLJGA0kOv12xujZN4f8SevHcpvrgOxN',
    },
    /* 必填：地域信息，可以直接填写字符串ap-guangzhou，支持的地域列表参考 https://cloud.tencent.com/document/api/382/52071#.E5.9C.B0.E5.9F.9F.E5.88.97.E8.A1.A8 */
    region: "ap-guangzhou",
    /* 非必填:
     * 客户端配置对象，可以指定超时时间等配置 */
    profile: {
      /* SDK默认用TC3-HMAC-SHA256进行签名，非必要请不要修改这个字段 */
      signMethod: "HmacSHA256",
      httpProfile: {
        /* SDK默认使用POST方法。
         * 如果你一定要使用GET方法，可以在这里设置。GET方法无法处理一些较大的请求 */
        reqMethod: "POST",
        /* SDK有默认的超时时间，非必要请不要进行调整
         * 如有需要请在代码中查阅以获取最新的默认值 */
        reqTimeout: 30,
        /**
         * 指定接入地域域名，默认就近地域接入域名为 sms.tencentcloudapi.com ，也支持指定地域域名访问，例如广州地域的域名为 sms.ap-guangzhou.tencentcloudapi.com
         */
        endpoint: "sms.tencentcloudapi.com"
      },
    },
  })

  /* 请求参数，根据调用的接口和实际情况，可以进一步设置请求参数
   * 属性可能是基本类型，也可能引用了另一个数据结构
   * 推荐使用IDE进行开发，可以方便的跳转查阅各个接口和数据结构的文档说明 */

  /* 帮助链接：
   * 短信控制台: https://console.cloud.tencent.com/smsv2
   * 腾讯云短信小助手: https://cloud.tencent.com/document/product/382/3773#.E6.8A.80.E6.9C.AF.E4.BA.A4.E6.B5.81 */
  const captcha = Math.floor(Math.random() * 1000000) // 生成6位随机验证码
  const params = {
    /* 短信应用ID: 短信SmsSdkAppId在 [短信控制台] 添加应用后生成的实际SmsSdkAppId，示例如1400006666 */
    // 应用 ID 可前往 [短信控制台](https://console.cloud.tencent.com/smsv2/app-manage) 查看
    SmsSdkAppId: "1400828821",
    /* 短信签名内容: 使用 UTF-8 编码，必须填写已审核通过的签名 */
    // 签名信息可前往 [国内短信](https://console.cloud.tencent.com/smsv2/csms-sign) 或 [国际/港澳台短信](https://console.cloud.tencent.com/smsv2/isms-sign) 的签名管理查看
    SignName: "鼎盛宏发公众号",
    /* 模板 ID: 必须填写已审核通过的模板 ID */
    // 模板 ID 可前往 [国内短信](https://console.cloud.tencent.com/smsv2/csms-template) 或 [国际/港澳台短信](https://console.cloud.tencent.com/smsv2/isms-template) 的正文模板管理查看
    TemplateId: "1825486",
    /* 模板参数: 模板参数的个数需要与 TemplateId 对应模板的变量个数保持一致，若无模板参数，则设置为空 */
    TemplateParamSet: [captcha],
    // TemplateParamSet: [captcha,'5'],
    /* 下发手机号码，采用 e.164 标准，+[国家或地区码][手机号]
     * 示例如：+8613711112222， 其中前面有一个+号 ，86为国家码，13711112222为手机号，最多不要超过200个手机号*/
    PhoneNumberSet: [`+86${phone}`],
    /* 用户的 session 内容（无需要可忽略）: 可以携带用户侧 ID 等上下文信息，server 会原样返回 */
    SessionContext: "",
    /* 短信码号扩展号（无需要可忽略）: 默认未开通，如需开通请联系 [腾讯云短信小助手] */
    ExtendCode: "",
    /* 国内短信无需填写该项；国际/港澳台短信已申请独立 SenderId 需要填写该字段，默认使用公共 SenderId，无需填写该字段。注：月度使用量达到指定量级可申请独立 SenderId 使用，详情请联系 [腾讯云短信小助手](https://cloud.tencent.com/document/product/382/3773#.E6.8A.80.E6.9C.AF.E4.BA.A4.E6.B5.81)。 */
    SenderId: "",
  }
  // 通过client对象调用想要访问的接口，需要传入请求对象以及响应回调函数
  client.SendSms(params, async function (err, response) {
    let yzm = params.TemplateParamSet[0]
    await UserModel.updateOne({ phone: phone }, { captcha: params.TemplateParamSet[0] })
    let token = jwt.sign(phone, 'token')
    let data = await UserModel.findOne({ phone: phone })
    if (data) {
      res.send({
        data, token, yzm
      })
    } else {
      res.send({ yzm })
    }

    // 请求异常返回，打印异常信息
    if (err) {
      console.log(err)
      return
    }
    // 请求正常返回，打印response对象
    console.log(response)
  })
})

// 忘记密码
router.post('/forgetpass', async (req, res) => {
  let body = req.body
  let data = await UserInfoModel.updateOne({ phone: body.phone }, { $set: { phone: body.phone, password: body.password } })
  if (data) {
    res.send({
      code: 200,
      msg: '登录成功',
      data,
    })
  } else {
    res.send({
      code: 201,
      msg: '用户或者密码错误',
    })
  }
})

// 人脸识别登入
router.post("/face", async (req, res) => {
  let user = req.body
  let users = await UserInfoModel.find()
  // let info = users.find(item => item.username == user.username)
  const tencentcloud = require("tencentcloud-sdk-nodejs-iai");
  const IaiClient = tencentcloud.iai.v20200303.Client;
  // var imageA = info.base
  let imageB = user.upload
  // 实例化一个认证对象，入参需要传入腾讯云账户secretId，secretKey,此处还需注意密钥对的保密
  // 密钥可前往https://console.cloud.tencent.com/cam/capi网站进行获取
  const clientConfig = {
    credential: {
      secretId: "AKIDEMHgNp20jDSSDm8F9A1d1B7rOgjX7Smx",
      secretKey: "FNLJGA0kOv12xujZN4f8SevHcpvrgOxN",
    },
    region: "ap-beijing",
    profile: {
      httpProfile: {
        endpoint: "iai.tencentcloudapi.com",
      },
    },
  };
  // 实例化要请求产品的client对象,clientProfile是可选的
  const client = new IaiClient(clientConfig);
  users.map(item => {
    let imageA = item.base
    const params = {
      "ImageA": imageA,
      "ImageB": imageB
    };
    client.CompareFace(params).then(
      (data) => {
        console.log(data.Score)
        if (data.Score >= 80) {
          res.send({
            code: 200,
            msg: "登陆成功",
            item,
          })
        } else {
          res.send({
            code: 203,
            msg: '查询无果'
          })
        }
      },
      (err) => {
        console.log("没有此人脸", err)
      }
    );
  })
})

// 用户删除
router.post('/delin', async function (req, res) {
  let body = req.body._value
  await UserInfoModel.deleteOne({ _id: body._id })
  res.send({
    'msg': '删除成功'
  })
})

// 用户密码修改
router.put('/editaddress', async function (req, res) {
  let body = req.body
  await UserInfoModel.updateOne({ _id: body._id }, { $set: { password: body.region } })
  res.send({
    'msg': '修改成功'
  })
})

// 搜索
router.get('/searchlist', async (req, res) => {
  let newname = new RegExp(req.query.rname)
  if (newname) {
    console.log(1);
    let data = await UserInfoModel.find({ name: newname }).populate(['role', 'division']).exec()
    res.send({ data })
  } else {
    console.log(2);
    let data = await UserInfoModel.find().populate(['role', 'division']).exec()
    res.send({ data })
  }
})

// 登录查看
router.get('/list', async (req, res) => {
  let data = await UserInfoModel.find().populate('role').exec()
  res.send({
    code: 200,
    data
  })
})


module.exports = router;
